/* eslint-disable camelcase */
import React, { useEffect, useRef, useState } from 'react';
import { List, WindowScroller } from 'react-virtualized';
import { Anchor, Row, Col, Input, Empty, Spin, Tooltip, Icon, Button } from 'antd';
import {
  getAssetCategoryComponent,
  getAssetCategory,
  getAssetCategoryDetail
} from '@api/knowledge';
import Drawer from './drawer';
import Form from './form';
import 'react-virtualized/styles.css';
import './style.less';
const prefixCls = 'asset-identification';
import _ from 'lodash';
import { connect } from 'react-redux';

let waitingForLoad = [];
let waitingForLoadIndex = 0;

const AssetForm = () => {
  const listRef = useRef();
  const refContainer = useRef();
  const [count, setCount] = useState(0);
  const [loading, setLoading] = useState(false);
  const [searchVal, setSearchVal] = useState('');
  const [inputVal, setInputVal] = useState('');
  const [componentList, setComponentList] = useState([]);
  const [componentChildrenList, setComponentChildrenList] = useState([]);
  const [visible, setVisible] = useState(false);
  const [fromVisible, setfromVisible] = useState(false);
  const [selectList, setSelectList] = useState([]);
  const [detail, setDetail] = useState();
  const [detailLoading, setDetailLoading] = useState(false);
  const [cacheRow, setCacheRow] = useState({});

  const getlist = async cache => {
    let params = {};
    searchVal ? (params.search = searchVal) : null;
    let cacheItem = listRef.current.Grid._renderedRowStartIndex;
    let { data } = await getAssetCategory();
    const { list } = _.get(data, 'data', []);
    setSelectList(list);
    getAssetCategory(params)
      .then(({ data }) => {
        const { list, count } = _.get(data, 'data', []);
        setCount(count);
        let rebuildList = [];
        // 数组扁平化
        list.forEach(item => {
          if (item._id) {
            let params = { _id: item._id, name: item.name, count: item.count };
            // 一级数据绑定第一个子级的id
            if (_.get(item.children, 'length') > 0) {
              params.subID = item.children[0]._id;
            }
            rebuildList.push(params);
          }
          if (_.get(item.children, 'length') !== 0) {
            item.children.map(cld => {
              rebuildList.push({ ...cld, isCld: true });
            });
          }
        });
        rebuildList = rebuildList.filter(r => r.count !== 0);
        setComponentList(
          rebuildList.map(item => ({
            ...item,
            product_list: [],
            more: 1,
            page: 0
          })) || []
        );
      })
      .finally(() => {
        setLoading(false);
        if (listRef && componentChildrenList.length) {
          listRef.current.scrollToRow(cache ? cacheItem : 0);
        }
      });
  };

  const change = async () => {
    waitingForLoad = [];
    waitingForLoadIndex = 0;
    await getlist(true);
  };

  const getDetail = param => {
    setVisible(true);
    setDetailLoading(true);
    getAssetCategoryDetail(param)
      .then(r => {
        setDetail(_.get(r, 'data.data', {}));
      })
      .catch(() => {})
      .finally(() => {
        setDetailLoading(false);
      });
  };
  useEffect(() => {
    setLoading(true);
    waitingForLoad = [];
    waitingForLoadIndex = 0;
    getlist();
  }, [searchVal]);

  // 监听更新右边组件每格的高度
  useEffect(() => {
    if (listRef && componentChildrenList.length) {
      listRef.current.recomputeRowHeights();
    }
  });

  useEffect(() => {
    setComponentChildrenList(componentList.filter(r => r.isCld));
  }, [componentList]);

  const changeAnchor = (e, link) => {
    e.preventDefault();
    e.stopPropagation();
    if (listRef) {
      // 如果点第一级 根据subID跳转到第二级第一个数据
      let id = link.title.props.children[1].props.children;
      let listIndex;
      if (!id) {
        id = link.title.props.children[0].props.children;
      }
      if (componentChildrenList.length) {
        componentChildrenList.find((r, index) => {
          if (r._id === id) {
            listIndex = index;
          }
        });
      }
      listRef.current.scrollToRow(listIndex);
    }
  };

  const renderEmpty = () => {
    return loading ? (
      <div style={{ textAlign: 'center', marginTop: 200, marginLeft: 150 }}>
        <Spin size="large" />
      </div>
    ) : (
      <div
        style={{
          textAlign: 'center',
          fontSize: '1.2em',
          color: '#8e8e8e',
          marginTop: 200,
          marginLeft: 150
        }}
      >
        <Empty description="亲, 换个关键词试试" image={Empty.PRESENTED_IMAGE_SIMPLE} />
      </div>
    );
  };

  const getRowHeight = ({ index = 0 }) => {
    const item = componentChildrenList[index];
    if (item && item.product_list.length !== 0) {
      const more = item.more ? 37 : 0;
      return Math.ceil(item.product_list.length / 5) * 40 + 105 + more;
    } else {
      return 140;
    }
  };

  const loadMore = (indexs, page) => {
    const id = indexs.map(index => {
      return componentChildrenList[index]._id || '';
    });
    let params = {
      page: page + 1,
      pageSize: 20,
      assetCategoryIdList: id
    };

    searchVal ? (params.search = searchVal) : null;
    getAssetCategoryComponent(params).then(res => {
      setComponentList(data => {
        indexs.forEach(index => {
          const rId = componentChildrenList[index]._id;
          const temp = res.data.data.component[rId] || [];
          if (!temp || temp.length === 0) {
            return [];
          }
          const { list, count, page } = temp;
          data.find((r, i) => {
            if (r._id === rId) {
              r.product_list = Array.from(new Set([...r.product_list, ...list]));
              r.more = r.product_list.length < count ? true : false;
              r.page = page;
              r.noData = r.product_list.length === 0;
              data[i] = r;
            }
          });
        });
        return [...data];
      });
    });
  };

  const renderRow = (theProps, call) => {
    const { index = 0, isVisible, key, style } = theProps;
    const item = componentChildrenList[index];
    const itemKey = item.name;
    const product_list = item.product_list || [];
    const noData = item.noData || false;
    const page = item.page || 0;
    const more = item.more || 0;
    if ((page === 0 && isVisible) || call) {
      if (!waitingForLoad.includes(index)) {
        waitingForLoad.push(index);
      }
      // eslint-disable-next-line no-use-before-define
      doLoadFirst(call);
    }
    return (
      <div id={itemKey} key={key} style={{ ...style, marginBottom: '10px' }}>
        <div className="render-item">
          <h3 className="text-lg">{itemKey}</h3>
          <div className={'componentItem'}>
            {product_list.length > 0 ? (
              product_list.map(datum => (
                <Tooltip
                  mouseEnterDelay={0.5}
                  overlayClassName="item-tooltip"
                  placement="bottom"
                  title={datum.product}
                  key={datum.product}
                >
                  <a
                    onClick={() => {
                      setCacheRow(datum._id);
                      getDetail({ knowledgeId: datum._id });
                    }}
                  >
                    {[datum.name?.cn, datum.product, datum.name?.en].find(i => i)}
                  </a>
                </Tooltip>
              ))
            ) : noData ? (
              <span>暂无数据</span>
            ) : (
              ''
            )}
            {more ? (
              <button className={'componentItem_more'} onClick={() => loadMore([index], page)}>
                <Icon type="down" />
              </button>
            ) : (
              <p style={{ 'margin-top': '30px' }} />
            )}
          </div>
        </div>
      </div>
    );
  };

  const _debounce = (fn, wait) => {
    let timer = null;
    return function() {
      if (timer !== null) {
        clearTimeout(timer);
      }
      timer = setTimeout(fn, wait);
    };
  };

  const doLoadFirst = _debounce(call => {
    if (waitingForLoad.length === waitingForLoadIndex && !call) {
      return;
    }
    const list = waitingForLoad.slice(waitingForLoadIndex);
    waitingForLoadIndex = waitingForLoad.length;
    loadMore(list, 0);
  }, 300);
  return (
    <div className={`${prefixCls}`}>
      <div className={`${prefixCls}-title`}>资产识别表({count})</div>
      <div className={`${prefixCls}-header`}>
        <Button
          type="primary"
          onClick={() => {
            setDetail();
            setfromVisible(true);
          }}
        >
          添加指纹知识库
        </Button>
        <div className={`${prefixCls}-header-right`}>
          <Input.Search
            placeholder={'请输入指纹名称'}
            onSearch={v => setSearchVal(v)}
            value={inputVal}
            onChange={e => setInputVal(e.target.value)}
            enterButton
          />
        </div>
      </div>
      <Row className="h-full" gutter={16}>
        {componentList.length ? (
          <>
            <Col span="5" className="h-100">
              {/* <div className="title-tiem">指纹名称</div> */}
              <div className="h-100 bg-white rounded-lg py-4">
                <Anchor
                  affix={false}
                  showInkInFixed
                  onClick={changeAnchor}
                  getContainer={() => (loading ? document.getElementById('contentScroll') : window)}
                >
                  {componentList.map((item, index) => (
                    <Anchor.Link
                      key={item._id}
                      href={`#${item._id}`}
                      index={index}
                      title={
                        <>
                          <span style={{ display: 'none' }}>{item._id}</span>
                          <span style={{ display: 'none' }}>{item.subID}</span>
                          <div
                            style={{ margin: item.isCld ? '0px 0px 0px 20px' : '0px 0px 0px 0px' }}
                          >
                            {item.name}({item.count})
                          </div>
                        </>
                      }
                    />
                  ))}
                </Anchor>
              </div>
            </Col>
          </>
        ) : null}
        <Col span={18} className="h-100">
          {/* <div className="title-tiem">指纹类别</div> */}
          <div className={'componentList'} id={'contentScroll'} ref={refContainer}>
            <WindowScroller scrollElement={refContainer.current}>
              {({ height, isScrolling, onChildScroll, scrollTop }) => (
                <List
                  ref={listRef}
                  autoHeight
                  height={height}
                  isScrolling={isScrolling}
                  onScroll={onChildScroll}
                  scrollTop={scrollTop}
                  width={1290}
                  style={{ width: '100%' }}
                  rowCount={componentChildrenList.length}
                  rowHeight={getRowHeight}
                  rowRenderer={renderRow}
                  scrollToAlignment="start"
                  noRowsRenderer={renderEmpty}
                />
              )}
            </WindowScroller>
          </div>
        </Col>
      </Row>
      <Drawer
        visible={visible}
        setVisible={setVisible}
        setfromVisible={setfromVisible}
        getList={getlist}
        renderRow={renderRow}
        loading={detailLoading}
        detail={detail}
        componentList={componentList}
        change={change}
        setDetail={setDetail}
      />
      <Form
        renderRow={renderRow}
        visible={fromVisible}
        setVisible={setfromVisible}
        detail={detail}
        componentList={selectList}
        getList={getlist}
        change={change}
        cacheRow={cacheRow}
        getDetail={getDetail}
      />
    </div>
  );
};
const mapStateToProps = state => {
  return {
    assetStats: _.get(state, 'assetManage.assetStats', {})
  };
};
export default connect(mapStateToProps)(AssetForm);
